//// 闭包使用
// 经常会看到闭包的身影，在定时器、事件监听器、AJAX请求、跨窗口通信、或者其它异步任务中。
// 一般来说，只要使用了回调函数，实际上就在使用闭包。

// 对于以下函数，虽然使用了闭包，在setTimeout的作用域内访问了外层函数作用域内的变量i.
// 但是因i的引用是共享的，所以这段代码会输出5个6
// 其它解释 : 代码试图假设在循环中的每个迭代都给自己捕获一个i的副本，尽管循环中的函数是在各个迭代中分别定义的。
// 但是i作用域却被封闭在一个共享的全局作用域中，只有一个实际的i
for(var i=0;i<5;i++) {
    setTimeout(function(){
        console.log(i);
    },1000);
}

// 可以再给函数封装一个作用域，这个作用域内的变量不再共享即可
for(var i=0;i<5;i++) {
    // IIFE函数每次迭代时都创建一个新的作用域，通过定义函数再创建一个作用域，并且将各次循环中i的值赋值到各个作用域内
    // j的作用域是各个函数所私有的，并不属于全局作用域
    (function(j){
        setTimeout(function(){
            console.log(j);
        });
    })(i)
}


// 不使用var的全局作用域，使用let形式的块级作用域，一样也可以哦。
for(let i=0;i<5;i++) {
    // i变量属于本函数内的作用域。
    setTimeout(function(){
        console.log(i);
    },1000);
}